package com.dykj.fireFighting.web.devicemanger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dykj.fireFighting.api.base.dev.entity.DeviceType;
import com.dykj.fireFighting.api.base.dev.service.IDeviceTypeService;
import com.dykj.fireFighting.api.base.enterprise.entity.Enterprise;
import com.dykj.fireFighting.api.base.enterprise.service.IEnterpriseService;
import com.dykj.fireFighting.api.base.file.service.OfficeService;
import com.dykj.fireFighting.api.base.rescue.entity.RescueInfo;
import com.dykj.fireFighting.api.base.rescue.service.IRescueInfoService;
import com.dykj.fireFighting.api.base.system.entity.SysDirectory;
import com.dykj.fireFighting.api.base.system.service.ISysDirectoryService;
import com.dykj.fireFighting.api.base.video.entity.Video;
import com.dykj.fireFighting.api.base.video.service.IVideoService;
import com.dykj.fireFighting.api.base.video.vo.VideoPlayVo;
import com.dykj.fireFighting.api.socialUnit.devHis.entity.CrtVo;
import com.dykj.fireFighting.api.socialUnit.devicemanger.dto.DeviceDto;
import com.dykj.fireFighting.api.socialUnit.devicemanger.entity.*;
import com.dykj.fireFighting.api.socialUnit.devicemanger.service.IDeviceRescueService;
import com.dykj.fireFighting.api.socialUnit.devicemanger.service.IDeviceService;
import com.dykj.fireFighting.api.socialUnit.devicemanger.service.IDeviceTraditionService;
import com.dykj.fireFighting.api.socialUnit.devicemanger.service.IEscapeRouteService;
import com.dykj.fireFighting.api.socialUnit.firemanger.entity.FireStation;
import com.dykj.fireFighting.api.socialUnit.firemanger.entity.HazardSources;
import com.dykj.fireFighting.api.socialUnit.firemanger.entity.KeyParts;
import com.dykj.fireFighting.api.socialUnit.firemanger.service.IFireStationService;
import com.dykj.fireFighting.api.socialUnit.firemanger.service.IHazardSourcesService;
import com.dykj.fireFighting.api.socialUnit.firemanger.service.IKeyPartsService;
import com.dykj.fireFighting.api.socialUnit.xfxg.entity.PatrolReportRecord;
import com.dykj.fireFighting.api.socialUnit.xfxg.service.IPatrolReportRecordService;
import com.dykj.fireFighting.common.core.annotation.AutoLog;
import com.dykj.fireFighting.common.core.api.CommonResult;
import com.dykj.fireFighting.common.core.exception.BaseException;
import com.dykj.fireFighting.common.core.utils.UUIDUtils;
import com.dykj.fireFighting.common.core.vo.LoginUserVo;
import com.dykj.fireFighting.common.core.vo.PageVo;
import com.dykj.fireFighting.common.starter.redisson.service.RedisService;
import com.dykj.fireFighting.web.base.shiro.ShiroUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jxls.reader.ReaderBuilder;
import org.jxls.reader.XLSReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.validation.Valid;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.*;


/**
 * 设备管理-智能设备接口
 *
 * @Author JacksonTu
 * @Date  2021-06-22 15:55:39
 */
@Slf4j
@Api(value = "设备管理-智能设备接口", tags = {"设备管理-智能设备接口"})
@RestController
@RequestMapping("device")
public class DeviceController {
    @DubboReference
    private ISysDirectoryService sysDirectoryService;
    @DubboReference
    private IEnterpriseService enterpriseService;
    @DubboReference
    private IPatrolReportRecordService patrolReportRecordService;
    @DubboReference
    private IRescueInfoService iRescueInfoService;
    @DubboReference
    private IDeviceTypeService deviceTypeService;
    @DubboReference(check = false)
    private OfficeService officeService;
    @Autowired
    private RedisService redisService;
    /**
     * 智能设备
     */
    @DubboReference
    private IDeviceService deviceService;
    /**
     * 传统设备
     */
    @DubboReference
    private IDeviceTraditionService deviceTraditionService;
    /**
     * 救援设备
     */
    @DubboReference
    private IDeviceRescueService deviceRescueService;
    /**
     * 监控设备
     */
    @DubboReference
    private IVideoService videoService;
    /**
     * 逃生通道
     */
    @DubboReference
    private IEscapeRouteService escapeRouteService;
    /**
     * 消防站
     */
    @DubboReference
    private IFireStationService fireStationService;
    /**
     * 重点部位
     */
    @DubboReference
    private IKeyPartsService keyPartsService;
    /**
     * 危险源
     */
    @DubboReference
    private IHazardSourcesService hazardSourcesService;

    /**
     * 设备管理-智能设备列表
     *
     * @return
     */
    @AutoLog(value = "设备管理-智能设备-分页列表查询")
    @ApiOperation(value = "设备管理-智能设备分页列表", notes = "设备管理-智能设备分页列表")
    @GetMapping("/list")
    @RequiresPermissions("device/list")
    public CommonResult<PageVo<Device>> treeGrid(DeviceDto deviceDto) {
        Long enterpriseId = ShiroUtil.getUser().getEnterpriseId();
        deviceDto.setUnitId(enterpriseId+"");
        PageVo<Device> page = deviceService.pageList(deviceDto);
        return CommonResult.success(page);
    }

    /**
     * 获取设备管理-智能设备信息
     */
    @AutoLog(value = "设备管理-智能设备-获取设备管理-智能设备信息")
    @ApiOperation(value = "获取设备管理-智能设备信息", notes = "获取设备管理-智能设备信息")
    @ApiImplicitParam(paramType = "path", name = "id", value = "主键ID", dataType = "String", required = true)
    @GetMapping("/info/{id}")
    @RequiresPermissions("device/info")
    public CommonResult<Device> info(@PathVariable("id") String id){
        Device device = deviceService.getById(id);
        return CommonResult.success(device);
    }
    /**
     * redis中获取设备，实时数据用
     */
    @ApiOperation(value = "redis中获取设备", notes = "redis中获取设备")
    @ApiImplicitParam(paramType = "path", name = "relationId", value = "relationid", dataType = "String", required = true)
    @GetMapping("/getInfo/{relationId}")
    public CommonResult<Device> getInfo(@PathVariable("relationId") String relationId){
        String[] strArry = relationId.split("-");
        Manufactor manufactor = JSON.parseObject((String) redisService.get(strArry[0]), Manufactor.class);
        if (manufactor == null) {
            return CommonResult.failed("无数据");
        }
        if (manufactor.getIsOnline().equals("0")){
            return CommonResult.failed("设备离线");
        }
        Device device = JSON.parseObject((String) redisService.get(relationId+"_realtime"), Device.class);
        if (device == null) {
            return CommonResult.failed("无数据");
        }
        return CommonResult.success(device);
    }
    /**
     * redis中获取Onenet设备，实时数据用
     */
    @ApiOperation(value = "redis中获取Onenet设备", notes = "redis中获取Onenet设备")
    @ApiImplicitParam(paramType = "path", name = "relationId", value = "relationid", dataType = "String", required = true)
    @GetMapping("/getOnenetInfo/{relationId}")
    public CommonResult<Device> getOnenetInfo(@PathVariable("relationId") String relationId){
        Device device = JSON.parseObject((String) redisService.get(relationId+"_realtime"), Device.class);
        if (device == null) {
            return CommonResult.failed("无数据");
        }
        return CommonResult.success(device);
    }

    /**
     * 设备管理-设备详情
     *
     * @return
     */
    @AutoLog(value = "设备管理-智能设备-智能设备详情")
    @ApiOperation(value = "设备管理-智能设备详情", notes = "设备管理-智能设备详情")
    @GetMapping("/detail")
    public CommonResult getDeviceDetail(String id, Integer tableType){
        HashMap<String, Object> map = new HashMap<>(8);
        //类型 0智能设备  1传统设备 2救援设备
        if (tableType == 0) {
            Device devicedetails = deviceService.bigDataDevice(id);
            String s = (String)redisService.get(devicedetails.getRelationId());
            if(StringUtils.isNotBlank(s)){//判断缓存中是否存在
                JSONObject o = JSON.parseObject(s);
                Object oo=o.get("status");
                if(null!=oo){
                    devicedetails.setStatus(oo.toString());
                }
            }
            map.put("zhineng",devicedetails);
        }else if (tableType == 1) {
            DeviceTradition deviceTradition = deviceTraditionService.getById(id);
            map.put("chuantong",deviceTradition);
        }else if (tableType == 2) {
            DeviceRescue deviceRescue = deviceRescueService.getById(id);
            map.put("jiuyuan",deviceRescue);
        }
        return CommonResult.success(map);
    }

    /**
     * 获取设备管理-智能设备信息-大数据页面用
     */
    @AutoLog(value = "设备管理-智能设备-获取设备管理-智能设备信息")
    @ApiOperation(value = "获取设备管理-智能设备信息", notes = "获取设备管理-智能设备信息")
    @ApiImplicitParam(paramType = "path", name = "id", value = "主键ID", dataType = "String", required = true)
    @GetMapping("/infoBigdata/{id}")
    @RequiresPermissions("device/info")
    public CommonResult<Map<String,Object>> infoBigdata(@PathVariable("id") String id){
        Map<String,Object> map=new HashMap<>();
        Device device = deviceService.getById(id);
        QueryWrapper<PatrolReportRecord> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("device_id",id);
        queryWrapper.orderByDesc("create_time");
        List<PatrolReportRecord> patrolReportRecord=patrolReportRecordService.list(queryWrapper);
        if(patrolReportRecord.size()>0){
            map.put("patrolReportRecord",patrolReportRecord.get(0));
        }
        map.put("deviceStatus",deviceService.getDeviceStatus(id));
        map.put("device",device);
        return CommonResult.success(map);
    }

    /**
     * 获取设备管理-智能设备详情
     */
    @AutoLog(value = "设备管理-智能设备-获取设备管理-智能设备详情")
    @ApiOperation(value = "获取设备管理-智能设备详情", notes = "获取设备管理-智能设备详情")
    @ApiImplicitParam(paramType = "path", name = "relationId", dataType = "String", required = true)
    @GetMapping("/details/{relationId}")
    @RequiresPermissions("device/info")
    public CommonResult<Object> details(@PathVariable("relationId") String relationId){
        Object device = deviceService.getDevicedetails(relationId);
        return CommonResult.success(device);
    }
    /**
     * 获取设备管理-智能设备详情
     */
    @AutoLog(value = "设备管理-智能设备-获取设备管理-智能设备详情")
    @ApiOperation(value = "获取设备管理-智能设备详情", notes = "获取设备管理-智能设备详情")
    @ApiImplicitParam(paramType = "path", name = "relationId", dataType = "String", required = true)
    @GetMapping("/getDeviceByRelationId/{relationId}")
    /*@RequiresPermissions("device/info")*/
    public CommonResult<Object> getDeviceByRelationId(@PathVariable("relationId") String relationId){
        Object device = deviceService.getDeviceByRelationId(relationId);
        return CommonResult.success(device);
    }
    /**
     * 保存设备管理-智能设备信息
     */
    @AutoLog(value = "设备管理-智能设备-保存设备管理-智能设备信息")
    @ApiOperation(value = "保存设备管理-智能设备信息", notes = "保存设备管理-智能设备信息")
    @PostMapping("/save")
    @RequiresPermissions("device/save")
    public CommonResult save(@Valid @RequestBody Device device) {
        try {
            LoginUserVo user = ShiroUtil.getUser();
            device.setId(UUIDUtils.get32UUID());
            device.setCreateBy(user.getId()+"");
            device.setUnitId(user.getEnterpriseId()+"");
            device.setCreateTime(new Date());
            //判断设备有没有主机
            if(StringUtils.isBlank(device.getMaufactorIdentification())){
                device.setRelationId(device.getId());
            }else{
                //判断设备所属系统
                if("728181".equals(device.getDevSysType())){//火灾自动报警系统
                    //判断设备有没有二次码
                    if(StringUtils.isBlank(device.getSecondaryCode())){//没有二次码
                        device.setRelationId(device.getMaufactorIdentification()+"-"+device.getHostNumber()+"-"+device.getLoopNumber()+"-"+device.getPartNumber());
                    }else{//有二次码
                        device.setRelationId(device.getMaufactorIdentification()+"-"+device.getSecondaryCode());
                    }
                }else if("728183".equals(device.getDevSysType())){
                    device.setRelationId(device.getMaufactorIdentification()+"-"+device.getChannelNumber()+"-1");
                }else if ("728185".equals(device.getDevSysType())) {
                    //if("2".equals(device.getMoniType())){
                        device.setRelationId(device.getMaufactorIdentification()+"-"+device.getChannelNumber()+"-2");
                    /*}else{
                        device.setRelationId(device.getMaufactorIdentification()+"-"+device.getChannelNumber()+"-1");
                    }*/
                }

            }
                deviceService.save(device);
                redisService.del(device.getRelationId());
            return CommonResult.success("添加成功");
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BaseException("运行异常，请联系管理员");
        }
    }

    /**
     * 修改设备管理-智能设备信息
     */
    @AutoLog(value = "设备管理-智能设备-修改设备管理-智能设备信息")
    @ApiOperation(value = "修改设备管理-智能设备信息", notes = "修改设备管理-智能设备信息")
    @PostMapping("/update")
    @RequiresPermissions("device/update")
    public CommonResult update(@Valid @RequestBody Device device) {
        try {
            Long id = ShiroUtil.getUser().getId();
            device.setUpdateBy(id+"");
            device.setUpdateTime(new Date());
            //判断设备有没有主机
            if(StringUtils.isBlank(device.getMaufactorIdentification())){
                device.setRelationId(device.getId());
            }else{
                //判断设备所属系统
                if("728181".equals(device.getDevSysType())){//火灾自动报警系统
                    //判断设备有没有二次码
                    if(StringUtils.isBlank(device.getSecondaryCode())){//没有二次码
                        device.setRelationId(device.getMaufactorIdentification()+"-"+device.getHostNumber()+"-"+device.getLoopNumber()+"-"+device.getPartNumber());
                    }else{//有二次码
                        device.setRelationId(device.getMaufactorIdentification()+"-"+device.getSecondaryCode());
                    }
                }else if("728183".equals(device.getDevSysType())){
                    device.setRelationId(device.getMaufactorIdentification()+"-"+device.getChannelNumber()+"-1");
                }else if ("728185".equals(device.getDevSysType())) {
                    //if("2".equals(device.getMoniType())){
                        device.setRelationId(device.getMaufactorIdentification()+"-"+device.getChannelNumber()+"-2");
                    //}else{
                      //  device.setRelationId(device.getMaufactorIdentification()+"-"+device.getChannelNumber()+"-1");
                    //}
                }

            }
                deviceService.updateById(device);
            redisService.del(device.getRelationId());
            return CommonResult.success("修改成功");
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BaseException("运行异常，请联系管理员");
        }
    }

    /**
     * 删除设备管理-智能设备信息
     */
    @AutoLog(value = "设备管理-智能设备-删除设备管理-智能设备信息")
    @ApiOperation(value = "删除设备管理-智能设备信息", notes = "删除设备管理-智能设备信息")
    @ApiImplicitParam(paramType = "query", name = "ids", value = "ID数组", dataType = "String", required = true, allowMultiple = true)
    @PostMapping("/delete")
    @RequiresPermissions("device/delete")
    public CommonResult delete(@RequestBody String[]ids) {
        try {
            for (String id : ids) {
                Device device = deviceService.getById(id);
                redisService.del(device.getRelationId());
            }
            deviceService.removeByIds(Arrays.asList(ids));
            return CommonResult.success("删除成功");
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BaseException("运行异常，请联系管理员");
        }
    }

    /**
     *批量导入火灾自动报警设备
     * @return
     */
    @PostMapping("/import")
    @RequiresPermissions("device/import")
    public CommonResult importDevice(@RequestParam("file") MultipartFile file, String maufactorIdentification, RedirectAttributes redirectAttributes){
        if (file.isEmpty()) {
            redirectAttributes.addFlashAttribute("message", "Please select a file to upload");
            return CommonResult.failed("请上传文件");
        }
        String fileName = file.getOriginalFilename();
        if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx") && !fileName.endsWith(".xlsm")) {
            redirectAttributes.addFlashAttribute("message", "Please select a correct file to upload");
            return CommonResult.failed("文件格式错误");
        }
        LoginUserVo user = ShiroUtil.getUser();
        List<DeviceType> devTypes = deviceTypeService.list();
        String xmlConfig = "uploadXml/devUpload.xml";
        try(InputStream xmlInputStream = getClass().getClassLoader().getResourceAsStream(xmlConfig)){
            XLSReader reader = ReaderBuilder.buildFromXML(xmlInputStream);
            try (InputStream xlsInputStream = new BufferedInputStream(file.getInputStream())){
                List<Device> deviceList = new ArrayList<>();
                Map<String, Object> beans = new HashMap<>();
                beans.put("deviceList", deviceList);
                reader.read(xlsInputStream, beans);
                Map<String,Object> params=new HashMap<>();
                params.put("deviceList",deviceList);
                params.put("deviceType",devTypes);
                params.put("user",user);
                params.put("maufactorIdentification",maufactorIdentification);
                int i = deviceService.importDevice(params);
                if(i>0){
                    return CommonResult.success("导入完成，为您更新了" + i + "条数据");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            return CommonResult.failed("导入失败，请检查上传的文件信息");
        }
        return CommonResult.failed("导入失败，请检查上传的文件信息");
    }

    @GetMapping("/deviceList")
    public CommonResult<List<Device>> getList(String deviceName) {
        List<Device>page = deviceService.getList(ShiroUtil.getUser().getEnterpriseId().toString(),deviceName);
        return CommonResult.success(page);
    }
    @GetMapping("/getDeviceTree")
    public CommonResult<List<DeviceTree>> getDeviceTree(){
        Long unitId = ShiroUtil.getUser().getEnterpriseId();
        List<SysDirectory> devSysType = sysDirectoryService.queryDataByType("dev_sys_type");
        List<DeviceTree> deviceTree = deviceService.getDeviceTree(devSysType,unitId + "");
        return CommonResult.success(deviceTree);
    }
    @GetMapping("/getDeviceTreeVideo")
    public CommonResult<List<DeviceTree>> getDeviceTreeVideo(){
        Long unitId = ShiroUtil.getUser().getEnterpriseId();
        List<SysDirectory> devSysType = sysDirectoryService.queryDataByType("dev_sys_type");
        List<DeviceTree> deviceTree = deviceService.getDeviceTreeVideo(devSysType,unitId + "");
        return CommonResult.success(deviceTree);
    }
    @GetMapping("/getDeviceUnit/{relationId}")
    public CommonResult<Object> getDeviceUnit(@PathVariable("relationId") String relationId){
        Device devicedetails = (Device)deviceService.getDevicedetails(relationId);
        Enterprise unit = enterpriseService.getById(devicedetails.getUnitId());
        //获取救援单位
        RescueInfo resuse = iRescueInfoService.getById(unit.getResuseId());
        //获取救援医院
        RescueInfo hospital = iRescueInfoService.getById(unit.getHospitalId());
        Map<String,Object> result=new HashMap<>();
        result.put("unit",unit);
        result.put("resuse",resuse);
        result.put("hospital",hospital);
        return CommonResult.success(result);
    }
    @GetMapping("/getDeviceVideo/{relationId}")
    public CommonResult<VideoPlayVo> getDeviceVideo(@PathVariable("relationId") String relationId){
        Device devicedetails = (Device)deviceService.getDevicedetails(relationId);
        return CommonResult.success(deviceService.getVideoByDeviceId(devicedetails.getId()));
    }
    @GetMapping("/getCrt/{relationId}")
    public CommonResult<CrtVo> getCrt(@PathVariable("relationId") String relationId){
        Device devicedetails = (Device)deviceService.getDevicedetails(relationId);
        return CommonResult.success(deviceService.getCrt(devicedetails.getId()));
    }
    @GetMapping("/getDeviceVideoByDevId/{deviceId}")
    public CommonResult<VideoPlayVo> getDeviceVideoByDevId(@PathVariable("deviceId") String deviceId){
        return CommonResult.success(deviceService.getVideoByDeviceId(deviceId));
    }
    /**
     *下载设备导入模板
     */
    @GetMapping("/getImportDeviceModel")
    public CommonResult getImportDeviceModel() throws Exception {
        Map<String,Object> map=new HashMap<>();
        String id = officeService.saveEXceltoMongo(map, null, "importDeviceModel.xls", "设备导入模板.xls");
        return CommonResult.success(id);
    }

    /**
     *
     * 根据设备id获取设备图标
     * @return
     */
    @GetMapping("/getIconByDeviceId/{deviceId}")
    public CommonResult getIconByDeviceId(@PathVariable("deviceId") String deviceId){
        String iconByDeviceId = deviceService.getIconByDeviceId(deviceId);
        return CommonResult.success(iconByDeviceId);
    }
    @GetMapping("/getEscapeRouteIcon/{deviceId}")
    public CommonResult getEscapeRouteIcon(@PathVariable("deviceId") String deviceId){
        String iconByDeviceId = deviceService.getEscapeRouteIcon(deviceId);
        return CommonResult.success(iconByDeviceId);
    }

    /**
     * 修改设备管理-智能设备信息
     */
    @AutoLog(value = "设备管理-智能设备-修改拓普瑞阈值-修改拓普瑞阈值")
    @ApiOperation(value = "修改拓普瑞阈值-修改拓普瑞阈值", notes = "修改拓普瑞阈值-修改拓普瑞阈值")
    @PostMapping("/editTopRui")
    public CommonResult editTopRui(@RequestBody TopRuiBean topRuiBean) {
        deviceService.editTopRui(topRuiBean);
        return CommonResult.success("发送成功");
    }
}
